fix(ingestion): skip mark-deleted for schemas whose table listing failed#27831
Conversation
When get_tables_name_and_type() raises an exception (e.g. transient connectivity failure), the schema's FQN is now recorded in `schemas_with_table_listing_errors`. mark_tables_as_deleted() skips those schemas instead of wiping all their OM tables — which was a silent data-loss bug when partial connectivity caused an empty database_source_state for that schema. Fixes open-metadata#18187 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
…tracking Two issues raised in code review of open-metadata#27831: 1. schemas_with_table_listing_errors not instance-scoped: added self.schemas_with_table_listing_errors = set() in CommonDbSourceService.__init__ for consistency with database_source_state. 2. Connectors overriding get_tables_name_and_type bypassed the guard: extracted _record_schema_listing_error() helper into DatabaseServiceSource and called it from UnityCatalog, Deltalake, Glue, and Salesforce overrides so the safety guard is universal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
|
Finding 1 — shared mutable class state: Added self.schemas_with_table_listing_errors = set() in CommonDbSourceService.init, making it instance-scoped like database_source_state. Finding 2 — connectors bypassing the guard: Extracted _record_schema_listing_error(schema_name) helper into DatabaseServiceSource (builds the FQN, adds to the set), then wired it into:
|
Code Review ✅ Approved 2 resolved / 2 findingsSkips mark-deleted operations for schemas with failed table listings to prevent data loss. Addresses the missing safety guard for overridden table listings and the inconsistent state initialization. ✅ 2 resolved✅ Bug: Connectors overriding get_tables_name_and_type bypass the safety guard
✅ Quality: schemas_with_table_listing_errors not reset in __init__ unlike database_source_state
OptionsDisplay: compact → Showing less information. Comment with these commands to change:
Was this helpful? React with 👍 / 👎 | Gitar |
Why
Fixes #18187
When
get_tables_name_and_type()raises an exception for a schema (e.g. a transient connectivity failure, permission error, or driver bug), the current code silently swallows the error and leavesdatabase_source_stateempty for that schema. On the next call tomark_tables_as_deleted(), OpenMetadata interprets the empty state as "all tables were deleted" and soft-deletes every table it knew about for that schema — silent data loss on every partial connectivity failure.What changed
common_db_source.py—get_tables_name_and_type()exception handlerWhen an exception is caught, the method now builds the schema FQN and records it in
self.schemas_with_table_listing_errors(inherited fromDatabaseServiceSource).database_service.py—DatabaseServiceSourceschemas_with_table_listing_errors: Set = set()class-level field.mark_tables_as_deleted()now checks this set before callingdelete_entity_from_source; schemas that failed listing are skipped with aWARNINGlog.The fix is in the shared base classes, so all database connectors (BigQuery, Snowflake, Redshift, …) are protected automatically.
Test plan
test_mark_deleted_tables_safety.py— 8 new unit tests covering:delete_entity_from_sourceis never calledmarkDeletedTables=Falsestill short-circuits everythingNoneFQN (schema not found in OM) is not added to the error set🤖 Generated with Claude Code